/*
 * @Author: 0x9DEFA478
 * @Date: 2024-08-18 14:19:57
 * @LastEditTime: 2024-09-22 21:33:11
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "H_ThreadScheduler.h"
#include "Peripheral.h"




/**
 * 该文件包含了所有测试逻辑代码
 * 
 * 该例子中：
 *    创建两个线程 stress0_Thread与stress1_Thread 与两个信号量 Event0与Event1
 *    stress0_Thread与tress1_Thread 分别等待 Event0与Event1 等待到信号后分别向 Event1与Event0 释放信号量(注意 是向另一个信号量释放信号)
 *    初始状态 stress0_Thread与tress1_Thread 都因信号量而阻塞, 直到其中一个信号量有信号
 * 
 *    通过触发SVC中断来调用测试中需要在中断中进行的部分
 *    释放其中一个信号量，以启动 stress0_Thread与stress1_Thread 的相互切换
 * 
 *    stress_Thread统计一段时间内的切换次数 得出性能结果
 * 
 *    该例子可以测试：
 *      1.中断释放信号量触发调度的速度
 *      2.线程释放信号量触发调度的速度
 *      3.大量线程阻塞时的调度速度
 * 
 * 
 */




//统计周期
#define Stress_Check_T                                            100
//如果Stress_IsTestISR不为0 则将释放信号量操作让SVC中断完成 这可以模拟中断操作信号量的情况
#define Stress_IsTestISR                                          1
//占位线程数量 将会创建Stress_IsExtThread个线程, 这些线程保持阻塞状态, 模拟阻塞链表很长的情况
#define Stress_IsExtThread                                        0

//内存分配
#define MemMalloc(in_Size)                                        MemoryMalloc_DTCM.Malloc(in_Size)
//信号量类型
#define Sem_Type                                                  H_TS_Event*
//新建信号
#define new_Sem                                                   new_H_TS_Event
//等待信号量
#define Sem_Take                                                  H_TS_Event_Take
//触发信号量
#define Sem_Give                                                  H_TS_Event_Triggering
//触发信号量 中断调用
#define Sem_Give_ISR                                              H_TS_Event_Triggering_ISR

typedef struct{
  Sem_Type Event0;
  Sem_Type Event1;
  volatile int cnt1;//切入stress1_Thread的次数
}StressData;

//用于调度测试
static int stress0_Thread(void* v){
  StressData* stressData;
  int ex_cnt0;
  int cnt0;
  int cnt1;
  int speed0;
  int speed1;
  int avg;
  System_Time_ms_Type lastT;

  stressData=v;

  ex_cnt0=0;
  cnt0=0;
  cnt1=0;
  avg=0;

  lastT=System_GetTime_ms();

  for(;;){
    Sem_Take(stressData->Event0);
    ex_cnt0++;
#if Stress_IsTestISR == 0
    Sem_Give(stressData->Event1);
#else
    oSVC_Call(Sem_Give_ISR,stressData->Event1);
#endif

    if((System_GetTime_ms()-lastT)>(Stress_Check_T-1)){

      speed0=ex_cnt0-cnt0;
      cnt0+=speed0;

      speed1=stressData->cnt1-cnt1;
      cnt1+=speed1;

      avg+=((speed0+speed1)-avg)/10;//低通滤波

      Printf("Stress_IsTestISR=%d\r\nspeed:%d/%dms\r\navg:%d/%dms\r\n",Stress_IsTestISR,speed0+speed1,Stress_Check_T,avg,Stress_Check_T);
      I_DebugPort_WriteSync();
      lastT=System_GetTime_ms();
    }
  }
}

//用于调度测试
static int stress1_Thread(void* v){

  StressData* stressData;

  stressData=v;

  for(;;){
    Sem_Take(stressData->Event1);
    stressData->cnt1++;
#if Stress_IsTestISR == 0
    Sem_Give(stressData->Event0);
#else
    oSVC_Call(Sem_Give_ISR,stressData->Event0);
#endif
  }
}




//占位线程 创建多个这样的线程模拟多线程阻塞情况
static int stress_OccThread(void* v){
  
  Sem_Type Event;

  Event=new_Sem();
  if(cH_IsNull(Event)){
    for(;;){
    }
  }
  Sem_Take(Event);//阻塞就完事了

  return 0;
}

//测试时间精度
// static int stress_TimeThread(void* v){
  
//   for(;;){
//     H_TS_ThreadSleep(100);
//     Printf("stress_TimeThread time:%dms\r\n",System_GetTime_ms());
//   }

//   // return 0;
// }

StressData* stressData;

void stressTest(){
  int i;
  H_TS_ThreadAttribute ThreadAttribute=vH_TS_ThreadAttributeDefault;


  stressData=MemMalloc(sizeof(StressData));

  stressData->cnt1=0;
  stressData->Event0=new_Sem();
  stressData->Event1=new_Sem();
  if(cH_IsNull(stressData->Event0)||cH_IsNull(stressData->Event1)){
    for(;;){
    }
  }

  //分别创建线程stress0_Thread stress1_Thread stress_Thread 优先级往低设置 stress_Thread的优先级要略高
  ThreadAttribute.Priority=vH_TS_ThreadMaxPriorityValue-1;
  ThreadAttribute.StackSize=1536;
  ThreadAttribute.ThreadName="stress0_Thread";
  H_TS_StartNewThread(stress0_Thread,stressData,&ThreadAttribute);
  ThreadAttribute.StackSize=768;
  ThreadAttribute.ThreadName="stress1_Thread";
  H_TS_StartNewThread(stress1_Thread,stressData,&ThreadAttribute);
  // H_TS_StartNewThread(stress_TimeThread,NULL,768,vH_TS_ThreadMaxPriorityValue-2,"stress_TimeThread");

  //万恶之源
  Sem_Give(stressData->Event0);
  
  ThreadAttribute.Priority=vH_TS_ThreadMaxPriorityValue-2;
  ThreadAttribute.StackSize=256;
  ThreadAttribute.ThreadName="Occ";
  for(i=0;i<Stress_IsExtThread;i++){
    if(NULL==H_TS_StartNewThread(stress_OccThread,NULL,&ThreadAttribute)){
      for(;;){
      }
    }
  }

}




// STM32H750VB 480MHz ARMCC V5.6
// O3 Optimize_for_Time_on Thread 195075/100ms
// O3 Optimize_for_Time_on Thread 195038/100ms 64eThread
// O3 Optimize_for_Time_on ISR 151396/100ms
// O3 Optimize_for_Time_on ISR 151361/100ms 64eThread
// O0 Optimize_for_Time_off Thread 149002/100ms
// O0 Optimize_for_Time_off Thread 148881/100ms 64eThread
// O0 Optimize_for_Time_off ISR 106103/100ms
// O0 Optimize_for_Time_off ISR 106913/100ms 64eThread



